package com.joysuch.wwyt.bp.service.impl;

import cn.zlg.common.util.CollectionUtils;
import com.google.common.collect.Lists;
import com.joysuch.wwyt.bp.bean.investigate.BpInvestigateStoreDetailBean;
import com.joysuch.wwyt.bp.bean.investigate.BpInvestigateStoreExcelBean;
import com.joysuch.wwyt.bp.entity.dto.BpInvestigateStoreDetailDto;
import com.joysuch.wwyt.bp.entity.investigate.BpInvestigateStore;
import com.joysuch.wwyt.bp.entity.investigate.BpInvestigateStoreDetail;
import com.joysuch.wwyt.bp.entity.investigate.BpSafeTableItem;
import com.joysuch.wwyt.bp.enums.SafeTableSourceTypes;
import com.joysuch.wwyt.bp.repository.BpInvestigatePlanRepository;
import com.joysuch.wwyt.bp.repository.BpInvestigateStoreDetailRepository;
import com.joysuch.wwyt.bp.repository.BpInvestigateStoreRepository;
import com.joysuch.wwyt.bp.repository.BpSafeTableItemDao;
import com.joysuch.wwyt.bp.service.BpInvestigateStoreDetailService;
import com.joysuch.wwyt.bp.service.BpInvestigateStoreService;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author ZhangDong
 * @Date 2020/3/25 10:48
 */
@Service
@Slf4j
@Transactional
public class BpInvestigateStoreDetailServiceImpl implements BpInvestigateStoreDetailService {

    @Autowired
    private BpInvestigateStoreDetailRepository detailRepository;
    @Autowired
    private BpInvestigateStoreRepository storeRepository;
    @Autowired
    private BpInvestigatePlanRepository planRepository;
    @Autowired
    private BpSafeTableItemDao safeTableItemDao;
    @Autowired
    private BpInvestigateStoreService bpInvestigateStoreService;

    @Override
    public ResultBean save(BpInvestigateStoreDetailBean bean) {
        Long id = bean.getId();
        BpInvestigateStoreDetail detail;
        if (id == null) {
            detail = new BpInvestigateStoreDetail();
            Long storeId = bean.getStoreId();
            if (storeId == null) {
                return ResultBean.fail(101, "新增时标准库id不能为空");
            } else {
                BpInvestigateStore bpInvestigateStore = storeRepository.findById(storeId).orElseThrow(() -> new RuntimeException("此类型已删除无法新增"));
                if (!bpInvestigateStore.getTopOrNot()) {
                    return ResultBean.fail(101, "请在正确的位置新增");
                }
            }
        } else {
            detail = detailRepository.findById(id).orElseThrow(() -> new RuntimeException("此数据不存在"));
        }
        //排查内容暂不做判重
        BeanUtils.copyProperties(bean, detail);
        detail = detailRepository.save(detail);
        //修改做排查表项目的数据同步
        if (id != null) {
            List<BpSafeTableItem> itemList = safeTableItemDao.findBySourceAndSourceId(SafeTableSourceTypes.HIDDEN_STORE, id);
            for (BpSafeTableItem item : itemList) {
                item.setContent(detail.getContent());
                item.setStandard(detail.getAccordance());
            }
            safeTableItemDao.saveAll(itemList);
        }
        return ResultBean.success(detail.getId());
    }

    @Override
    public ResultBean delete(Long id) {
        //如果有安全排查表关联不给删
        List<BpSafeTableItem> itemList = safeTableItemDao.findBySourceAndSourceId(SafeTableSourceTypes.HIDDEN_STORE, id);
        if (!org.springframework.util.CollectionUtils.isEmpty(itemList)) {
            return ResultBean.fail(101, "该排查标准已被排查表绑定，请先解除绑定再删除");
        }
        detailRepository.deleteById(id);
        return ResultBean.defaultSuccessResult();
    }

    @Override
    public ResultBean page(Pageable pageable, Long storeId) {
        pageable = PageDataUtils.addOrderByDesc(pageable, "createTime");
        if (storeId == 0) {
            Page<BpInvestigateStoreDetail> all = detailRepository.findAll(pageable);
            return ResultBean.pageData(convertToDto(all.getContent()), all.getTotalElements());
        }
        BpInvestigateStore bpInvestigateStore = storeRepository.findById(storeId).orElseThrow(() -> new RuntimeException("操作失败"));
        List<Long> storeIdList = Lists.newArrayList();
        if (!bpInvestigateStore.getTopOrNot()) {
            List<BpInvestigateStore> storeList = storeRepository.findByParentId(storeId);
            for (BpInvestigateStore store : storeList) {
                if (!store.getTopOrNot()) {
                    List<BpInvestigateStore> stores = storeRepository.findByParentId(store.getId());
                    for (BpInvestigateStore investigateStore : stores) {
                        storeIdList.add(investigateStore.getId());
                    }
                } else {
                    storeIdList.add(store.getId());
                }
            }
        } else {
            storeIdList.add(storeId);
        }
        if (CollectionUtils.isEmpty(storeIdList)) {
            return ResultBean.pageData(Lists.newArrayList(), 0);
        }
        Specification<BpInvestigateStoreDetail> query = (Root<BpInvestigateStoreDetail> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) -> {
            List<Predicate> predicates = Lists.newArrayList();
            CriteriaBuilder.In<Object> in = cb.in(root.get("storeId"));
            for (Long aLong : storeIdList) {
                in.value(aLong);
            }
            predicates.add(in);
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Page<BpInvestigateStoreDetail> all = detailRepository.findAll(query, pageable);
        for (BpInvestigateStoreDetail storeDetail : all) {
            BpInvestigateStore store = storeRepository.findById(storeDetail.getStoreId()).orElse(new BpInvestigateStore());
            String checkTypeName = store.getCheckTypeName();
            storeDetail.setStoreName(checkTypeName == null ? "" : checkTypeName);
        }
        return ResultBean.pageData(convertToDto(all.getContent()), all.getTotalElements());
    }

    private List<BpInvestigateStoreDetailDto> convertToDto(List<BpInvestigateStoreDetail> all) {
        List<BpInvestigateStoreDetailDto> list = new ArrayList<>();
        for (BpInvestigateStoreDetail bpInvestigateStoreDetail : all) {
            //根据标准库id查询名称
            String storename = bpInvestigateStoreService.getNameById(bpInvestigateStoreDetail.getStoreId());
            BpInvestigateStoreDetailDto bpInvestigateStoreDetailDto = new BpInvestigateStoreDetailDto();
            BeanUtils.copyProperties(bpInvestigateStoreDetail,bpInvestigateStoreDetailDto);
            bpInvestigateStoreDetailDto.setStorename(storename);
            list.add(bpInvestigateStoreDetailDto);
        }
        return list;
    }
    
    @Override
    public BpInvestigateStoreDetail getById(Long id) {
        BpInvestigateStoreDetail storeDetail = detailRepository.findById(id).orElseThrow(() -> new RuntimeException("操作失败"));
        BpInvestigateStore bpInvestigateStore = storeRepository.findById(storeDetail.getStoreId()).orElseThrow(() -> new RuntimeException("操作失败"));
        storeDetail.setStoreName(bpInvestigateStore.getCheckTypeName());
        return storeDetail;
    }

    @Override
    public ResultBean importData(List<BpInvestigateStoreExcelBean> list) {
//        //移除末尾全部为空的多余值
//        int index = 0;
//        boolean hasCount = false;
//        for (int i = 0; i < list.size(); i++) {
//            BpInvestigateStoreExcelBean bean = list.get(i);
//            if (bean.getContent() != null || bean.getAccordance() != null || bean.getCurStore() != null
//                    || bean.getParentStore() != null || bean.getGrandStore() != null) {
//                index = i;
//                hasCount = true;
//            }
//        }
//        if (!hasCount) {
//            return ResultBean.success("导入0条数据");
//        }
//        list = list.subList(0, index + 1);
//        if (org.springframework.util.CollectionUtils.isEmpty(list)) {
//            return ResultBean.success("导入0条数据");
//        }
//        List<BpInvestigateStore> allStoreList = storeRepository.findAll();
//        List<Integer> lengthNotList = Lists.newArrayList();
//        List<Integer> checkTypeNotList = Lists.newArrayList();
//        int successCount = 0;
//        //数据处理
//        for (int i = 0; i < list.size(); i++) {
//            BpInvestigateStoreExcelBean bean = list.get(i);
//            //判断非空，内容长度
//            String content = bean.getContent();
//            String accordance = bean.getAccordance();
//            if (StringUtils.isEmpty(content) || StringUtils.isEmpty(accordance)
//                    || content.length() > 512 || accordance.length() > 512) {
//                lengthNotList.add(i + 3);
//                continue;
//            }
//            String curStore = bean.getCurStore();
//            String parentStore = bean.getParentStore();
//            String grandStore = bean.getGrandStore();
//            //检查类型非空，64字符限制
//            boolean b = judgeType(curStore, parentStore, grandStore, checkTypeNotList, i + 3);
//            if (!b) {
//                continue;
//            }
//
//            //上上级
//            Map<String, Long> grandMap = allStoreList.stream().filter(r -> r.getParentId() == 0)
//                    .collect(Collectors.toMap(r -> r.getCheckTypeName(), r -> r.getId()));
//            Long grandId;
//            if (grandMap.containsKey(grandStore)) {
//                grandId = grandMap.get(grandStore);
//            } else {
//                BpInvestigateStore bpInvestigateStore = new BpInvestigateStore(grandStore, 0L, false);
//                BpInvestigateStore save = storeRepository.save(bpInvestigateStore);
//                allStoreList.add(save);
//                grandId = save.getId();
//            }
//            //上级
//            Map<String, Long> parentMap = allStoreList.stream().filter(r -> r.getParentId().equals(grandId))
//                    .collect(Collectors.toMap(r -> r.getCheckTypeName(), r -> r.getId()));
//            Long parentId;
//            if (parentMap.containsKey(parentStore)) {
//                parentId = parentMap.get(parentStore);
//            } else {
//                BpInvestigateStore bpInvestigateStore = new BpInvestigateStore(parentStore, grandId, false);
//                BpInvestigateStore save = storeRepository.save(bpInvestigateStore);
//                allStoreList.add(save);
//                parentId = save.getId();
//            }
//            //当前级
//            final Long parentTempId = parentId;
//            Map<String, Long> curMap = allStoreList.stream().filter(r -> r.getParentId().equals(parentTempId))
//                    .collect(Collectors.toMap(r -> r.getCheckTypeName(), r -> r.getId()));
//            Long curId;
//            if (curMap.containsKey(curStore)) {
//                curId = curMap.get(curStore);
//            } else {
//                BpInvestigateStore bpInvestigateStore = new BpInvestigateStore(curStore, parentId, true);
//                BpInvestigateStore save = storeRepository.save(bpInvestigateStore);
//                allStoreList.add(save);
//                curId = save.getId();
//            }
//            BpInvestigateStoreDetail storeDetail = new BpInvestigateStoreDetail(curId, curStore, content, accordance);
//            detailRepository.save(storeDetail);
//            successCount++;
//        }
//        StringBuilder builder = new StringBuilder();
//        if (!org.springframework.util.CollectionUtils.isEmpty(lengthNotList)) {
//            builder.append("第" + lengthNotList + "行'排查内容'或者'排查依据'不符合要求 ");
//        }
//        if (!org.springframework.util.CollectionUtils.isEmpty(checkTypeNotList)) {
//            builder.append("第" + checkTypeNotList + "行'标准库'不符合要求 ");
//        }
//        builder.append("总共成功" + successCount + "条,失败" + (list.size() - successCount) + "条");
//        return ResultBean.success(builder.toString());
        return ResultBean.defaultSuccessResult();
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @Override
    public ResultBean deletes(List<Long> ids) {
        List<String> message = new ArrayList<>();
        for (Long id : ids) {
            try {
                delete(id);
            } catch (IllegalArgumentException e) {
                message.add(e.getMessage());
                log.error(e.getMessage(), e);
            } catch (Exception ex) {
                log.error(ex.getMessage(), ex);
            }
        }
        return ResultBean.success(message);
    }

    /**
     * 判断检查类型是否符合非空，64字符限制要求
     * columnNo: excel中行号
     * 返回值: false 不继续处理数据
     */
    private boolean judgeType(String curStore, String parentStore, String grandStore,
                              List<Integer> checkTypeNotList, Integer columnNo) {
        if (StringUtils.isEmpty(curStore) || curStore.length() > 64) {
            checkTypeNotList.add(columnNo);
            return false;
        }
        if (StringUtils.isEmpty(parentStore) || parentStore.length() > 64) {
            checkTypeNotList.add(columnNo);
            return false;
        }
        if (StringUtils.isEmpty(grandStore) || grandStore.length() > 64) {
            checkTypeNotList.add(columnNo);
            return false;
        }
        return true;
    }
}
